#include "Ape/InputListener.h"

Camera* InputListener::mCamera = NULL;
RenderWindow* InputListener::mWindow = NULL;
Overlay* InputListener::mDebugOverlay = NULL;
OIS::InputManager* InputListener::mInputManager = NULL;
OIS::Mouse*    InputListener::mMouse = NULL;
OIS::Keyboard* InputListener::mKeyboard = NULL;
OIS::JoyStick* InputListener::mJoy = NULL;

InputListener::InputListener()
{

	mWindow = GameSystemManager::getSingleton()->getOgre()->getWindow();

	LogManager::getSingletonPtr()->logMessage("*** Initializing OIS ***");
	ParamList pl;
	size_t windowHnd = 0;
	std::ostringstream windowHndStr;

	mWindow->getCustomAttribute("WINDOW", &windowHnd);
	windowHndStr << windowHnd;
	pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));

	//Remove this to hide windows mouse
	
	pl.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_FOREGROUND" )));
	pl.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_NONEXCLUSIVE")));
	pl.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_FOREGROUND")));
	pl.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_NONEXCLUSIVE")));

	mInputManager = InputManager::createInputSystem( pl );

	//Create all devices (We only catch joystick exceptions here, as, most people have Key/Mouse)
	mKeyboard = static_cast<Keyboard*>(mInputManager->createInputObject( OISKeyboard, true ));
	mMouse = static_cast<Mouse*>(mInputManager->createInputObject( OISMouse, true ));
	
	//Set initial mouse clipping size
	windowResized(mWindow);

	mDebugOverlay = OverlayManager::getSingleton().getByName("Core/DebugOverlay");
	//showDebugOverlay();
	
	//Register as a Window listener
	mMouse->setEventCallback(this);
	mKeyboard->setEventCallback(this);
	
	WindowEventUtilities::addWindowEventListener(mWindow, this);


}

InputListener::~InputListener()
{

	//Remove ourself as a Window listener
	WindowEventUtilities::removeWindowEventListener(mWindow, this);
				windowClosed(mWindow);

}


void InputListener::updateStats()
{
	static String currFps = "Current FPS: ";
	static String avgFps = "Average FPS: ";
	static String bestFps = "Best FPS: ";
	static String worstFps = "Worst FPS: ";
	static String tris = "Triangle Count: ";
	static String batches = "Batch Count: ";

	// update stats when necessary
	try {
		OverlayElement* guiAvg = OverlayManager::getSingleton().getOverlayElement("Core/AverageFps");
		OverlayElement* guiCurr = OverlayManager::getSingleton().getOverlayElement("Core/CurrFps");
		OverlayElement* guiBest = OverlayManager::getSingleton().getOverlayElement("Core/BestFps");
		OverlayElement* guiWorst = OverlayManager::getSingleton().getOverlayElement("Core/WorstFps");

		const RenderTarget::FrameStats& stats = mWindow->getStatistics();
		guiAvg->setCaption(avgFps + StringConverter::toString(stats.avgFPS));
		guiCurr->setCaption(currFps + StringConverter::toString(stats.lastFPS));
		guiBest->setCaption(bestFps + StringConverter::toString(stats.bestFPS)
			+" "+StringConverter::toString(stats.bestFrameTime)+" ms");
		guiWorst->setCaption(worstFps + StringConverter::toString(stats.worstFPS)
			+" "+StringConverter::toString(stats.worstFrameTime)+" ms");

		OverlayElement* guiTris = OverlayManager::getSingleton().getOverlayElement("Core/NumTris");
		guiTris->setCaption(tris + StringConverter::toString(stats.triangleCount));

		OverlayElement* guiBatches = OverlayManager::getSingleton().getOverlayElement("Core/NumBatches");
		guiBatches->setCaption(batches + StringConverter::toString(stats.batchCount));

		OverlayElement* guiDbg = OverlayManager::getSingleton().getOverlayElement("Core/DebugText");
		guiDbg->setCaption(mDebugText);
	}
	catch(...) {  }
}

bool InputListener::frameStarted(const FrameEvent& evt)
{
	//if(!mWindow->isActive())


	return true;
}
bool InputListener::frameEnded(const FrameEvent& evt)
{
	updateStats();
	return true;
}

bool InputListener::mouseMoved( const OIS::MouseEvent &arg )
{
	return true;
}
bool InputListener::keyPressed( const OIS::KeyEvent &arg )
{
	return true;
}

//Adjust mouse clipping area
void InputListener::windowResized(RenderWindow* rw)
{
	unsigned int width, height, depth;
	int left, top;
	rw->getMetrics(width, height, depth, left, top);

	const OIS::MouseState &ms = mMouse->getMouseState();
	ms.width = width;
	ms.height = height;
}

//Unattach OIS before window shutdown (very important under Linux)
void InputListener::windowClosed(RenderWindow* rw)
{
	//Only close for window that created OIS (the main window in these demos)
	if( rw == mWindow )
	{
		if( mInputManager )
		{
			mInputManager->destroyInputObject( mMouse );
			mInputManager->destroyInputObject( mKeyboard );
			mInputManager->destroyInputObject( mJoy );

			OIS::InputManager::destroyInputSystem(mInputManager);
			mInputManager = 0;
		}
	}
}


void InputListener::showDebugOverlay() //bool show
{
	bShowDebugOverlay = !bShowDebugOverlay;
	if (mDebugOverlay)
	{
		if (bShowDebugOverlay)
			mDebugOverlay->show();
		else
			mDebugOverlay->hide();
	}
}


